import java.util.*;
import java.io.*;

// ============ 基础类定义 ============

// 角色基类
abstract class Character {
    protected String name;
    protected int hp;
    protected int maxHp;
    protected int attack;
    
    public Character(String name, int hp, int attack) {
        this.name = name;
        this.hp = hp;
        this.maxHp = hp;
        this.attack = attack;
    }
    
    public boolean isAlive() {
        return hp > 0;
    }
    
    public void takeDamage(int damage) {
        hp -= damage;
        if (hp < 0) {
            hp = 0;
        }
    }
    
    public void heal(int amount) {
        hp += amount;
        if (hp > maxHp) hp = maxHp;
    }
    
    // 抽象方法，由子类实现
    public abstract int attackTarget();
    
    // Getter方法
    public String getName() {
        return name;
    }
    public int getHp() {
        return hp;
    }
    public int getMaxHp() {
        return maxHp;
    }
    public int getAttack() {
        return attack;
    }
}

// 玩家类
class Player extends Character {
    private ArrayList<Item> backpack;
    private int experience;
    private Set<String> achievements;
    
    public Player(String name) {
        super(name, 100, 20);
        this.backpack = new ArrayList<>();
        this.experience = 0;
        this.achievements = new HashSet<>();
        
        // 初始道具
        backpack.add(new HealingPotion());
        backpack.add(new HealingPotion());
    }
    
    @Override
    public int attackTarget() {
        Random rand = new Random();
        int damage = attack + rand.nextInt(10) - 5; // 随机波动±5
        return Math.max(1, damage); // 最少造成1点伤害
    }
    
    public void addItem(Item item) {
        backpack.add(item);
        System.out.println("获得物品: " + item.getName());
    }
    
    public void useItem(String itemName) {
        for (int i = 0; i < backpack.size(); i++) {
            Item item = backpack.get(i);
            if (item.getName().equals(itemName)) {
                item.use(this);
                backpack.remove(i);
                return;
            }
        }
        System.out.println("背包中没有 " + itemName);
    }
    
    public void showBackpack() {
        System.out.println("\n=== 背包 ===");
        if (backpack.isEmpty()) {
            System.out.println("背包是空的");
        } else {
            for (int i = 0; i < backpack.size(); i++) {
                System.out.println((i + 1) + ". " + backpack.get(i).getName());
            }
        }
    }
    
    public void gainExperience(int exp) {
        experience += exp;
        System.out.println("获得经验: " + exp + " (总经验: " + experience + ")");
    }
    
    public void addAchievement(String achievement) {
        if (achievements.add(achievement)) {
            System.out.println("*** 获得成就: " + achievement + " ***");
        }
    }
    
    public ArrayList<Item> getBackpack() {
        return backpack;
    }
    public Set<String> getAchievements() {
        return achievements;
    }
}

// 敌人类
class Enemy extends Character {
    public Enemy(String name, int hp, int attack) {
        super(name, hp, attack);
    }
    
    @Override
    public int attackTarget() {
        Random rand = new Random();
        int damage = attack + rand.nextInt(6) - 3; // 随机波动±3
        return Math.max(1, damage);
    }
}

// ============ 物品系统 ============

abstract class Item {
    protected String name;
    protected String description;
    
    public Item(String name, String description) {
        this.name = name;
        this.description = description;
    }
    
    public abstract void use(Player player);
    
    public String getName() {
        return name;
    }
    public String getDescription() {
        return description;
    }
}

// 治疗药水
class HealingPotion extends Item {
    public HealingPotion() {
        super("治疗药水", "恢复30点生命值");
    }
    
    @Override
    public void use(Player player) {
        player.heal(30);
        System.out.println("使用了治疗药水，恢复30点生命值！");
    }
}

// 力量药水
class StrengthPotion extends Item {
    public StrengthPotion() {
        super("力量药水", "永久增加5点攻击力");
    }
    
    @Override
    public void use(Player player) {
        player.attack += 5;
        System.out.println("使用了力量药水，攻击力永久增加5点！");
    }
}

// ============ 场景系统 ============

class GameScene {
    private String id;
    private String title;
    private String description;
    private HashMap<Integer, String> choices;
    private Enemy enemy; // 可选的敌人
    private ArrayList<Item> items; // 可获得的物品
    private String puzzle; // 谜题
    private String puzzleAnswer; // 谜题答案
    
    public GameScene(String id, String title, String description) {
        this.id = id;
        this.title = title;
        this.description = description;
        this.choices = new HashMap<>();
        this.items = new ArrayList<>();
    }
    
    public void addChoice(int number, String nextSceneId) {
        choices.put(number, nextSceneId);
    }
    
    public void setEnemy(Enemy enemy) {
        this.enemy = enemy;
    }
    
    public void addItem(Item item) {
        items.add(item);
    }
    
    public void setPuzzle(String puzzle, String answer) {
        this.puzzle = puzzle;
        this.puzzleAnswer = answer;
    }
    
    // Getter方法
    public String getId() {
        return id;
    }
    public String getTitle() {
        return title;
    }
    public String getDescription() {
        return description;
    }
    public HashMap<Integer, String> getChoices() {
        return choices;
    }
    public Enemy getEnemy() {
        return enemy;
    }
    public ArrayList<Item> getItems() {
        return items;
    }
    public String getPuzzle() {
        return puzzle;
    }
    public String getPuzzleAnswer() {
        return puzzleAnswer;
    }
}

// ============ 游戏主类 ============

public class AdventureGame {
    private HashMap<String, GameScene> scenes;
    private Player player;
    private Scanner scanner;
    private Stack<String> sceneHistory; // 用于回退功能
    private String currentSceneId;
    
    public AdventureGame() {
        scenes = new HashMap<>();
        scanner = new Scanner(System.in);
        sceneHistory = new Stack<>();
        initializeGame();
    }
    
    private void initializeGame() {
        // 创建玩家
        System.out.print("请输入你的角色名字: ");
        String playerName = scanner.nextLine();
        player = new Player(playerName);
        
        // 初始化场景
        createScenes();
        
        System.out.println("\n欢迎来到冒险世界, " + playerName + "!");
        System.out.println("输入 'help' 查看帮助信息");
        System.out.println("输入 'back' 可以回退到上一个场景");
    }
    
    private void createScenes() {
        // 起始场景
        GameScene start = new GameScene("start", "神秘森林入口", 
            "你站在一片神秘森林的入口。前方有两条路：\n" +
            "左边的路看起来安全但普通，右边的路散发着神秘的光芒。");
        start.addChoice(1, "safe_path");
        start.addChoice(2, "mysterious_path");
        scenes.put("start", start);
        
        // 安全路径
        GameScene safePath = new GameScene("safe_path", "安全小径", 
            "你选择了安全的路径。路上很平静，你发现了一些有用的物品。");
        safePath.addItem(new HealingPotion());
        safePath.addChoice(1, "village");
        scenes.put("safe_path", safePath);
        
        // 神秘路径
        GameScene mysteriousPath = new GameScene("mysterious_path", "神秘小径", 
            "你踏上了神秘的路径。前方出现了一个哥布林挡住了去路！");
        mysteriousPath.setEnemy(new Enemy("哥布林", 40, 15));
        mysteriousPath.addChoice(1, "cave_entrance");
        scenes.put("mysterious_path", mysteriousPath);
        
        // 村庄
        GameScene village = new GameScene("village", "和平村庄", 
            "你来到了一个宁静的村庄。村民们很友善，给了你一些补给。");
        village.addItem(new HealingPotion());
        village.addItem(new StrengthPotion());
        village.setPuzzle("村长的谜题：什么东西有头没有手，有尾没有腿？", "钢笔");
        village.addChoice(1, "cave_entrance");
        scenes.put("village", village);
        
        // 洞穴入口
        GameScene caveEntrance = new GameScene("cave_entrance", "神秘洞穴入口", 
            "你来到了一个神秘洞穴的入口。洞穴深处传来奇异的声音。\n" +
            "这里可能隐藏着宝藏，但也充满了危险。");
        caveEntrance.addChoice(1, "treasure_room");
        caveEntrance.addChoice(2, "dragon_lair");
        scenes.put("cave_entrance", caveEntrance);
        
        // 宝藏室
        GameScene treasureRoom = new GameScene("treasure_room", "宝藏室", 
            "你找到了宝藏室！里面有珍贵的物品。");
        treasureRoom.addItem(new StrengthPotion());
        treasureRoom.addItem(new HealingPotion());
        treasureRoom.setPuzzle("宝箱的密码：1+1等于多少？", "2");
        treasureRoom.addChoice(1, "end");
        scenes.put("treasure_room", treasureRoom);
        
        // 龙之巢穴
        GameScene dragonLair = new GameScene("dragon_lair", "龙之巢穴", 
            "你进入了龙之巢穴！一条小龙出现在你面前！");
        dragonLair.setEnemy(new Enemy("小龙", 80, 25));
        dragonLair.addChoice(1, "end");
        scenes.put("dragon_lair", dragonLair);
        
        // 结束
        GameScene end = new GameScene("end", "冒险结束", 
            "恭喜你完成了这次冒险！你的经历将成为传说。");
        scenes.put("end", end);
    }
    
    public void startGame() {
        currentSceneId = "start";
        
        while (true) {
            if (currentSceneId.equals("end")) {
                showEndGame();
                break;
            }
            
            GameScene currentScene = scenes.get(currentSceneId);
            if (currentScene == null) {
                System.out.println("场景错误！游戏结束。");
                break;
            }
            
            displayScene(currentScene);
            
            // 处理特殊内容
            handleSceneContent(currentScene);
            
            // 如果玩家死亡，游戏结束
            if (!player.isAlive()) {
                System.out.println("\n游戏结束！你在冒险中失败了。");
                break;
            }
            
            // 显示选择并处理用户输入
            if (!currentScene.getChoices().isEmpty()) {
                handlePlayerChoice(currentScene);
            }
        }
    }
    
    private void displayScene(GameScene scene) {
        System.out.println("\n" + "=".repeat(50));
        System.out.println("📍 " + scene.getTitle());
        System.out.println("=".repeat(50));
        System.out.println(scene.getDescription());
        System.out.println("\n💖 生命值: " + player.getHp() + "/" + player.getMaxHp());
        System.out.println("⚔️ 攻击力: " + player.getAttack());
    }
    
    private void handleSceneContent(GameScene scene) {
        // 处理物品
        for (Item item : scene.getItems()) {
            player.addItem(item);
        }
        
        // 处理战斗
        if (scene.getEnemy() != null) {
            handleBattle(scene.getEnemy());
        }
        
        // 处理谜题
        if (scene.getPuzzle() != null) {
            handlePuzzle(scene);
        }
    }
    
    private void handleBattle(Enemy enemy) {
        System.out.println("\n⚔️ 战斗开始！你遇到了 " + enemy.getName());
        
        while (player.isAlive() && enemy.isAlive()) {
            // 显示状态
            System.out.println("\n--- 战斗状态 ---");
            System.out.println("你的生命值: " + player.getHp() + "/" + player.getMaxHp());
            System.out.println(enemy.getName() + "的生命值: " + enemy.getHp());
            
            // 玩家回合
            System.out.println("\n你的回合!");
            System.out.println("1. 攻击");
            System.out.println("2. 使用物品");
            System.out.print("选择行动: ");
            
            int choice = getIntInput();
            
            if (choice == 1) {
                // 攻击
                int damage = player.attackTarget();
                enemy.takeDamage(damage);
                System.out.println("你对 " + enemy.getName() + " 造成了 " + damage + " 点伤害！");
                
                if (!enemy.isAlive()) {
                    System.out.println(enemy.getName() + " 被击败了！");
                    player.gainExperience(20);
                    player.addAchievement("击败 " + enemy.getName());
                    break;
                }
            } else if (choice == 2) {
                // 使用物品
                useItemInBattle();
            }
            
            // 敌人回合
            if (enemy.isAlive()) {
                int damage = enemy.attackTarget();
                player.takeDamage(damage);
                System.out.println(enemy.getName() + " 对你造成了 " + damage + " 点伤害！");
                
                if (!player.isAlive()) {
                    System.out.println("你被击败了...");
                    break;
                }
            }
        }
    }
    
    private void useItemInBattle() {
        player.showBackpack();
        if (player.getBackpack().isEmpty()) {
            System.out.println("背包是空的！");
            return;
        }
        
        System.out.print("输入要使用的物品名称: ");
        String itemName = scanner.nextLine();
        player.useItem(itemName);
    }
    
    private void handlePuzzle(GameScene scene) {
        System.out.println("\n🧩 " + scene.getPuzzle());
        System.out.print("你的答案: ");
        String answer = scanner.nextLine();
        
        if (answer.equals(scene.getPuzzleAnswer())) {
            System.out.println("✅ 答对了！");
            player.addAchievement("解谜高手");
            player.gainExperience(10);
        } else {
            System.out.println("❌ 答错了，正确答案是: " + scene.getPuzzleAnswer());
        }
    }
    
    private void handlePlayerChoice(GameScene scene) {
        System.out.println("\n--- 选择你的行动 ---");
        
        // 显示场景选择
        for (Map.Entry<Integer, String> entry : scene.getChoices().entrySet()) {
            String nextSceneTitle = scenes.get(entry.getValue()).getTitle();
            System.out.println(entry.getKey() + ". 前往 " + nextSceneTitle);
        }
        
        // 显示其他选项
        System.out.println("98. 查看背包");
        System.out.println("99. 查看成就");
        System.out.println("输入 'back' 返回上一场景");
        System.out.println("输入 'save' 保存游戏");
        System.out.println("输入 'load' 读取游戏");
        System.out.println("输入 'help' 查看帮助");
        
        System.out.print("请选择: ");
        String input = scanner.nextLine();
        
        // 处理特殊命令
        if (input.equals("back")) {
            goBack();
            return;
        } else if (input.equals("save")) {
            saveGame();
            return;
        } else if (input.equals("load")) {
            loadGame();
            return;
        } else if (input.equals("help")) {
            showHelp();
            return;
        }
        
        try {
            int choice = Integer.parseInt(input);
            
            if (choice == 98) {
                player.showBackpack();
                return;
            } else if (choice == 99) {
                showAchievements();
                return;
            }
            
            // 处理场景选择
            if (scene.getChoices().containsKey(choice)) {
                sceneHistory.push(currentSceneId); // 保存当前场景用于回退
                currentSceneId = scene.getChoices().get(choice);
            } else {
                System.out.println("无效的选择，请重新输入。");
            }
        } catch (NumberFormatException e) {
            System.out.println("请输入有效的数字或命令。");
        }
    }
    
    private void goBack() {
        if (sceneHistory.isEmpty()) {
            System.out.println("无法回退，这是游戏开始。");
        } else {
            currentSceneId = sceneHistory.pop();
            System.out.println("已回退到上一个场景。");
        }
    }
    
    private void showAchievements() {
        System.out.println("\n=== 成就列表 ===");
        if (player.getAchievements().isEmpty()) {
            System.out.println("还没有获得任何成就");
        } else {
            for (String achievement : player.getAchievements()) {
                System.out.println("🏆 " + achievement);
            }
        }
    }
    
    private void showHelp() {
        System.out.println("\n=== 游戏帮助 ===");
        System.out.println("• 输入数字选择行动");
        System.out.println("• back - 返回上一个场景");
        System.out.println("• save - 保存当前游戏进度");
        System.out.println("• load - 读取保存的游戏");
        System.out.println("• 98 - 查看背包");
        System.out.println("• 99 - 查看成就");
    }
    
    private void saveGame() {
        try {
            FileWriter writer = new FileWriter("savegame.txt");
            writer.write(player.getName() + "\n");
            writer.write(player.getHp() + "\n");
            writer.write(player.getAttack() + "\n");
            writer.write(currentSceneId + "\n");
            writer.close();
            System.out.println("游戏已保存！");
        } catch (IOException e) {
            System.out.println("保存失败: " + e.getMessage());
        }
    }
    
    private void loadGame() {
        try {
            Scanner fileScanner = new Scanner(new File("savegame.txt"));
            String name = fileScanner.nextLine();
            int hp = Integer.parseInt(fileScanner.nextLine());
            int attack = Integer.parseInt(fileScanner.nextLine());
            String sceneId = fileScanner.nextLine();
            
            // 重新创建玩家
            player = new Player(name);
            player.hp = hp;
            player.attack = attack;
            currentSceneId = sceneId;
            
            fileScanner.close();
            System.out.println("游戏已读取！");
        } catch (Exception e) {
            System.out.println("读取失败: " + e.getMessage());
        }
    }
    
    private void showEndGame() {
        System.out.println("\n" + "=".repeat(50));
        System.out.println("🎉 游戏结束！");
        System.out.println("=".repeat(50));
        System.out.println("感谢 " + player.getName() + " 的精彩冒险！");
        System.out.println("最终状态:");
        System.out.println("• 生命值: " + player.getHp() + "/" + player.getMaxHp());
        System.out.println("• 攻击力: " + player.getAttack());
        System.out.println("• 总成就数: " + player.getAchievements().size());
        showAchievements();
    }
    
    private int getIntInput() {
        while (true) {
            try {
                return Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.print("请输入有效数字: ");
            }
        }
    }
    
    public static void main(String[] args) {
        AdventureGame game = new AdventureGame();
        game.startGame();
    }
}